﻿using RabbitMQ.Client;
using Server;
using System;
using System.Text;

namespace Producter
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("-------------------发布者确认模式------------------");
            var msg = "";
            do
            {
                msg = Console.ReadLine(); ;
                Producer.SendQueueMsg(msg);
                Console.WriteLine("******消息已经发送*****");

            } while (msg.ToLower() != "out");

        }
    }
}
class Producer
{
    private static readonly RabbitMQ.Client.ConnectionFactory rabbitMqFactory = CommonConnectionFactory.rabbitMqFactory;

    public static void SendQueueMsg(string msg = "0")
    {
        string ExchangeName = "发布者确认交换机";
        string QueueName = "发布者确认队列";
        using (IConnection conn = rabbitMqFactory.CreateConnection())
        {
            using (IModel channel = conn.CreateModel())
            {
                //direct：默认，根据routingKey完全匹配，好处是先匹配再发送
                //topic：根据绑定关键字通配符规则匹配、比较灵活
                //Fanout：不需要指定routingkey，相当于群发
                //header：不太常用，可以自定义匹配规则
                //声明交换机

                channel.ConfirmSelect();//开启发布者确认

                channel.ExchangeDeclare(ExchangeName, ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                channel.QueueDeclare(QueueName, durable: true, autoDelete: false, exclusive: false, arguments: null);
                channel.QueueBind(QueueName, ExchangeName, routingKey: "发布者确认模式");

                var props = channel.CreateBasicProperties();
                props.Persistent = true;

                var msgBody = Encoding.UTF8.GetBytes($@"{msg}");
                channel.BasicPublish(exchange: ExchangeName, routingKey: "发布者确认模式", basicProperties: props, body: msgBody);

                //可以发送一批消息后,调用该方法;也可以每发一条调用一次.　　　　　　 
                if (channel.WaitForConfirms())
                {
                    Console.WriteLine("---------------------------发送是成功了");
                }
                else
                {
                    Console.WriteLine("send is failed");
                    //实际应用中,这里需要添加发送消息失败的处理逻辑.
                    //如果是发送一批消息,那么只要有一条失败,则所有的消息发送都会失败.
                }

                channel.Close();
            }
        }
    }
}